package com.jrtc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jrtc.base.config.constants.PublicConstants;
import com.jrtc.base.entity.bo.*;
import com.jrtc.base.entity.vo.*;
import com.jrtc.dao.*;
import com.jrtc.service.ExerciserecordService;
import com.jrtc.service.PatientService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 患者运动记录表(Exerciserecord)表服务实现类
 *
 * @author makejava
 * @since 2022-03-21 17:34:12
 */
@Service("exerciserecordService")
public class ExerciserecordServiceImpl implements ExerciserecordService
{
    @Resource
    private ExerciserecordDao exerciserecordDao;
    @Resource
    private FoodrecordDao foodrecordDao;
    @Resource
    private HealthplanDao healthplanDao;
    @Resource
    private ExerciseprescriptionDao exerciseprescriptionDao;
    @Resource
    private PatientExerciseprescriptionDao patientExerciseprescriptionDao;
    @Resource
    private PatientService patientService;
    @Resource
    private CatchBallRecordDao catchBallRecordDao;
    @Resource
    private FingerFuckRecordDao fingerFuckRecordDao;
    @Resource
    private ExerciseReportDao exerciseReportDao;
    @Resource
    private ArticulusReportDao articulusReportDao;

    /**
     * 通过ID查询单条数据
     *
     * @param exerciserecordId 主键
     * @return 实例对象
     */
    @Override
    public Exerciserecord queryById(Integer exerciserecordId) {
        return this.exerciserecordDao.queryById(exerciserecordId);
    }

    /**
     * 查询多条数据
     *
     * @param offset 查询起始位置
     * @param limit 查询条数
     * @return 对象列表
     */
    @Override
    public List<Exerciserecord> queryAllByLimit(int offset, int limit) {
        return this.exerciserecordDao.queryAllByLimit(offset, limit);
    }

    @Override
    public IPage<Exerciserecord> queryExerciserecordList(Exerciserecord exerciserecord)
    {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<Exerciserecord> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(exerciserecord.getPageNo(), exerciserecord.getPageSize());
        IPage<Exerciserecord> exerciserecordPage = this.exerciserecordDao.queryExerciserecordList(page, exerciserecord);
        return exerciserecordPage;
    }
    /**
     * 新增数据
     *
     * @param exerciserecord 实例对象
     * @return 实例对象
     */
    @Override
    public Exerciserecord insert(Exerciserecord exerciserecord) {
        this.exerciserecordDao.insert(exerciserecord);
        return exerciserecord;
    }

    /**
     * 修改数据
     *
     * @param exerciserecord 实例对象
     * @return 实例对象
     */
    @Override
    public Exerciserecord update(Exerciserecord exerciserecord) {
        this.exerciserecordDao.update(exerciserecord);
        return this.queryById(exerciserecord.getExerciserecordId());
    }

    /**
     * 通过主键删除数据
     *
     * @param exerciserecordId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer exerciserecordId) {
        return this.exerciserecordDao.deleteById(exerciserecordId) > 0;
    }

    /**
     * 患者运动记录
     * */
    @Override
    public List<ExerciserecordVo> selectExerciserecordList(Integer patientId) throws Exception {
        if (patientId != null){
            List<Exerciserecord> exerciserecords = exerciserecordDao.selectExerciserecordList(patientId);
            if (exerciserecords != null && exerciserecords.size() > 0){
                List<ExerciserecordVo> exerciserecordVoList = new ArrayList<>();
                for (Exerciserecord exerciserecord : exerciserecords) {
                    ExerciserecordVo exerciserecordVo = new ExerciserecordVo();
                    exerciserecordVo.setExerciserecordId(exerciserecord.getExerciserecordId());
                    exerciserecordVo.setPrescriptionName(exerciserecord.getPrescriptionName());
                    exerciserecordVo.setDuration(exerciserecord.getDuration());
                    exerciserecordVo.setDegreeOfCompletion(exerciserecord.getDegreeOfCompletion() + "%");
                    exerciserecordVo.setPain(exerciserecord.getPain());
                    exerciserecordVo.setFatigue(exerciserecord.getFatigue());
                    exerciserecordVo.setDate(exerciserecord.getDate());
                    exerciserecordVoList.add(exerciserecordVo);
                }
                return exerciserecordVoList;
            }
            else {
                throw new Exception("未查到数据");
            }
        }
        else {
            throw new Exception("缺少必要参数");
        }
    }

    /**
     * 患者训练记录
     * */
    @Override
    public TrainingRecordVo selectTrainingRecordVo(Integer patientId) throws Exception {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        if (patientId != null && patientId != 0){
            List<Exerciserecord> exerciserecords = exerciserecordDao.selectExerciserecordList(patientId);
            Date time = new Date();
            String date = format.format(time);

            Integer consume = 0;
            if (exerciserecords != null && exerciserecords.size() > 0){
                for (Exerciserecord exerciserecord : exerciserecords) {
                    if (exerciserecord.getDate().equals(date)){
                        consume = consume + exerciserecord.getExerciseValue();
                    }
                }
            }

            List<Foodrecord> foodrecords = foodrecordDao.selectFoodrecord(patientId);
            Integer ingest = 0;
            if (foodrecords != null && foodrecords.size() > 0){
                for (Foodrecord foodrecord : foodrecords) {
                    if (foodrecord.getFoodDate().equals(date)){
                        ingest = ingest + foodrecord.getFoodValue();
                    }
                }
            }

            List<Healthplan> healthplans = new ArrayList<>();
            List<PatientExerciseprescription> patientExerciseprescriptionList = patientExerciseprescriptionDao.selectPatientCollect(patientId);
            if (patientExerciseprescriptionList != null && patientExerciseprescriptionList.size() > 0){
                for (PatientExerciseprescription patientExerciseprescription : patientExerciseprescriptionList) {
                    Healthplan healthplan = healthplanDao.selectHealthplan(patientExerciseprescription.getHealthPlanId());
                    healthplans.add(healthplan);
                }
            }

            Integer completedCourseNum = 0;
            Integer everyDayNum = 0;
            if (healthplans != null && healthplans.size() > 0){
                for (Healthplan healthplan : healthplans) {
                    //判断当前日期是否在康复计划时间内
                    if ((healthplan.getHealthplanStarttime().compareTo(time) == 0 ||
                            healthplan.getHealthplanStarttime().compareTo(time) == -1) &&
                            (healthplan.getHealthplanEndtime().compareTo(time) == 0 ||
                                    healthplan.getHealthplanEndtime().compareTo(time) == 1)){
                        String week = week(time);
                        //判断当前星期是否在康复计划内
                        if (healthplan.getHealthplanWeekday().contains(week)){
                            for (HealthplanPrescription healthplanPrescription : healthplan.getHealthplanPrescriptionList()) {
                                if (healthplan.getHealthplanId() == healthplanPrescription.getHealthplanId()){
                                    for (Exerciseprescription exerciseprescription : healthplan.getExerciseprescriptionList()) {
                                        //获取康复计划对应的运动处方id
                                        if (healthplanPrescription.getPrescriptionId() == exerciseprescription.getPrescriptionId()){
                                            everyDayNum++;
                                            for (Exerciserecord exerciserecord : healthplan.getExerciserecordList()) {
                                                //获取运动处方对应运动记录信息
                                                if (healthplanPrescription.getPrescriptionId() == exerciserecord.getPrescriptionId()){
                                                    //获取今日待完成课程数量
                                                    if (exerciserecord.getIsexercisefinish().equals(PublicConstants.IsExerciseFinish.FALSE.getValue())){
                                                        completedCourseNum++;
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            TrainingRecordVo trainingRecordVo = new TrainingRecordVo();
            trainingRecordVo.setConsume(consume);
            trainingRecordVo.setIngest(ingest);
            trainingRecordVo.setCompletedCourseNum(completedCourseNum);
            trainingRecordVo.setEveryDayNum(everyDayNum);
            return trainingRecordVo;
        }
        else {
            throw new Exception("缺少必要参数");
        }
    }

    /**
     * 添加报告
     * */
    @Override
    public InsertReportVo insertReport(Exerciserecord exerciserecord) throws Exception {
        if (exerciserecord.getIdCard() == null || exerciserecord.getIdCard().equals("")){
            exerciserecord.setIdCard("130223199107160617");
        }

        SimpleDateFormat format = new SimpleDateFormat("YYYY-MM-dd");
        InsertReportVo insertReportVo = new InsertReportVo();

        if (exerciserecord.getPrescriptionId() != null &&
                exerciserecord.getPrescriptionId() != 0 &&
                !exerciserecord.getPrescriptionId().equals("")){
            Exerciseprescription exerciseprescription = exerciseprescriptionDao.queryById(exerciserecord.getPrescriptionId());
            if (exerciseprescription != null){
                exerciserecord.setPrescriptionName(exerciseprescription.getPrescriptionName());
            }
        }

        Date date = new Date();
        Patient patient = null;
        if (exerciserecord.getIdCard() != null){
            patient = patientService.patient(exerciserecord.getIdCard());
        }

        exerciserecord.setDate(format.format(date));
        exerciserecord.setExerciseWeektime(week(date));

        if (patient != null){
            exerciserecord.setPatientId(patient.getPatientId());
        }


        int insert = exerciserecordDao.insert(exerciserecord);
        if (insert <= 0){
            throw new Exception("添加失败");
        }

        Integer time = 0;
        List<TrendVo> trendVoList = new ArrayList<>();
        PatientExerciseprescription patientExerciseprescription = patientExerciseprescriptionDao.queryById(exerciserecord.getHealthPlanId());
        if (patientExerciseprescription != null){

            List<Exerciserecord> exerciserecordList = exerciserecordDao.exerciserecord(patient.getPatientId(), patientExerciseprescription.getFavouriteId(), format.format(date));
            if (exerciserecordList != null && exerciserecordList.size() > 0){
                for (Exerciserecord tmpExerciserecord : exerciserecordList) {
                    if (tmpExerciserecord.getDuration() != null && !tmpExerciserecord.getDuration().equals("")){
                        time = time + Integer.parseInt(tmpExerciserecord.getDuration());
                    }

                    TrendVo trendVo = new TrendVo();
                    trendVo.setDate(tmpExerciserecord.getDate());
                    trendVo.setActual(tmpExerciserecord.getActual());
                    trendVo.setOptimal(tmpExerciserecord.getOptimal());
                    trendVoList.add(trendVo);
                }
            }
        }

        insertReportVo.setTime(time.toString());
        insertReportVo.setTrendVoList(trendVoList);
        insertReportVo.setPrecautions("注意事项: \n恢复正常的副运动是关节的生理运动重建的前提,若在尚未恢复正常副运动之前试图改善受限关节的生理运动范围或增强肌力,其结果将适得其反,可引起关节的炎症、疼痛、渗出,关节积血,关节囊韧带松弛甚至骨折等。因此,对于由关节囊内损伤所引起的关节活动受限,康复治疗应首先恢复关节的松弛度和活动性。在没有异常的关节囊外因素存在的情况下,通过恢复关节的副运动就可能达到改善关节的运动受限、缓解疼痛、渗出吸收和改善功能活动的目的。");
        return insertReportVo;
    }

    /**
     * 治疗记录
     * */
    @Override
    public List<TreatmentRecordsVo> treatmentRecords(Integer id) {
        List<TreatmentRecordsVo> treatmentRecordsVoList = new ArrayList<>();
        List<Exerciserecord> exerciserecordList = exerciserecordDao.selectExerciserecordList(id);
        if (exerciserecordList != null && exerciserecordList.size() > 0){
            for (Exerciserecord exerciserecord : exerciserecordList) {
                if (exerciserecord.getActionType() != null){
                    if (exerciserecord.getActionType().equals(PublicConstants.RecordEnum.ExercisePrescription.getValue())){
                        ExerciseReport exerciseReport = exerciseReportDao.queryById(exerciserecord.getActionTypeId());
                        if (exerciseReport != null){
                            TreatmentRecordsVo treatmentRecordsVo = new TreatmentRecordsVo();
                            treatmentRecordsVo.setId(exerciserecord.getExerciserecordId());
                            treatmentRecordsVo.setOldId(exerciseReport.getId());
                            treatmentRecordsVo.setName(exerciserecord.getPrescriptionName());
                            treatmentRecordsVo.setClassification(PublicConstants.RecordEnum.ExercisePrescription.getValue());
                            treatmentRecordsVo.setTime(exerciserecord.getDuration());
                            treatmentRecordsVo.setDate(exerciserecord.getDate());
                            treatmentRecordsVoList.add(treatmentRecordsVo);
                        }
                    }
                    else if (exerciserecord.getActionType().equals(PublicConstants.RecordEnum.SmallBall.getValue())){
                        CatchBallRecord catchBallRecord = catchBallRecordDao.catchBallRecordById(exerciserecord.getActionTypeId());
                        if (catchBallRecord != null){
                            TreatmentRecordsVo treatmentRecordsVo = new TreatmentRecordsVo();
                            treatmentRecordsVo.setId(exerciserecord.getExerciserecordId());
                            treatmentRecordsVo.setOldId(catchBallRecord.getCatchBallRecordId());
                            treatmentRecordsVo.setName(exerciserecord.getPrescriptionName());
                            treatmentRecordsVo.setClassification(PublicConstants.RecordEnum.SmallBall.getValue());
                            treatmentRecordsVo.setTime(exerciserecord.getDuration());
                            treatmentRecordsVo.setDate(exerciserecord.getDate());
                            treatmentRecordsVoList.add(treatmentRecordsVo);
                        }
                    }
                    else if (exerciserecord.getActionType().equals(PublicConstants.RecordEnum.FingerFuck.getValue())){
                        FingerFuckRecord fingerFuckRecord = fingerFuckRecordDao.fingerFuckRecordById(exerciserecord.getActionTypeId());
                        if (fingerFuckRecord != null){
                            TreatmentRecordsVo treatmentRecordsVo = new TreatmentRecordsVo();
                            treatmentRecordsVo.setId(exerciserecord.getExerciserecordId());
                            treatmentRecordsVo.setOldId(fingerFuckRecord.getFingerFuckRecordId());
                            treatmentRecordsVo.setName(exerciserecord.getPrescriptionName());
                            treatmentRecordsVo.setClassification(PublicConstants.RecordEnum.FingerFuck.getValue());
                            treatmentRecordsVo.setTime(exerciserecord.getDuration());
                            treatmentRecordsVo.setDate(exerciserecord.getDate());
                            treatmentRecordsVoList.add(treatmentRecordsVo);
                        }
                    }
                    else if (exerciserecord.getActionType().equals(PublicConstants.RecordEnum.Joint.getValue())){
                        ArticulusReport articulusReport = articulusReportDao.queryById(exerciserecord.getActionTypeId());
                        if (articulusReport != null){
                            TreatmentRecordsVo treatmentRecordsVo = new TreatmentRecordsVo();
                            treatmentRecordsVo.setId(exerciserecord.getExerciserecordId());
                            treatmentRecordsVo.setOldId(articulusReport.getId());
                            treatmentRecordsVo.setName(exerciserecord.getPrescriptionName());
                            treatmentRecordsVo.setClassification(PublicConstants.RecordEnum.Joint.getValue());
                            treatmentRecordsVo.setTime(exerciserecord.getDuration());
                            treatmentRecordsVo.setDate(exerciserecord.getDate());
                            treatmentRecordsVoList.add(treatmentRecordsVo);
                        }
                    }
                }
            }
        }
        return treatmentRecordsVoList;
    }

    /**
     * 运动记录图表
     * */
    @Override
    public ExerciseReportVo exerciseChart(Integer id) {
        ExerciseReportVo exerciseReportVo = new ExerciseReportVo();
        ExerciseReport exerciseReport = exerciseReportDao.queryById(id);
//        JSONObject jsonObject = JSONObject.parseObject(jsonObject);
//
//        String versionInfoStr = jsonObject.getString("inventoryDTOs");
//
//        List<InventoryDTO> inventoryDTOs = JSON.parseArray(versionInfoStr, InventoryDTO.class);
//        //康复质量评分
//        private List<IdNameInfoVo> healthScore;
//
//        //动作匹配度
//        private List<IdNameInfoVo> actionMatch;
//
//        //动作匹配度%
//        private Integer count;
//
//        //心率
//        private List<IdNameInfoVo> heart;
//
//        //血氧饱和度
//        private List<IdNameInfoVo> bloodSaturation;
//
//        //HRV监测
//        private List<IdNameInfoVo> HRV;
//
//        //血氧容积波
//        private List<IdNameInfoVo> bloodArea;
//
//        //运动处方表主键
//        private Integer prescriptionId;
//
//        //康复计划id
//        private Integer healthplanId;
//
//        //时长
//        private String duration;
//
//        //实际康复质量评分
//        private Integer actual;
//
//        //最佳康复质量评分
//        private Integer optimal;
//
//        //患者证件号
//        private String idCard;
//
//        //运动处方名称
//        private String prescriptionName;
//
//        //日期
//        private String date;
//
//        //运动时间是周几
//        private String exerciseWeektime;
//
//        //患者id
//        private Integer patientId;
//
//        /*-------------------------返回用----------------------------------*/
//
//        /** 运动康复周期 */
//        private Integer cycle;
//
//        /** 完成康复治疗 */
//        private Integer finish;
//
//        /** 总训练时长 */
//        private String time;
//
//        /** 康复走势图列表 */
//        private List<TrendVo> trendVoList;
        return exerciseReportVo;
    }

    /**
     * 星期枚举赋值
     * */
    public String week(Date date) throws Exception {
        SimpleDateFormat weekTime = new SimpleDateFormat("EEEE");
        String weekName = weekTime.format(date);
        if (weekName != null && !weekName.equals("")){
            switch (weekName){
                case "星期一":
                    weekName = PublicConstants.Week.On_Monday.getValue();
                    break;
                case "星期二":
                    weekName = PublicConstants.Week.Tuesday.getValue();
                    break;
                case "星期三":
                    weekName = PublicConstants.Week.Wednesday.getValue();
                    break;
                case "星期四":
                    weekName = PublicConstants.Week.Thursday.getValue();
                    break;
                case "星期五":
                    weekName = PublicConstants.Week.Friday.getValue();
                    break;
                case "星期六":
                    weekName = PublicConstants.Week.Saturday.getValue();
                    break;
                case "星期日":
                    weekName = PublicConstants.Week.Sunday.getValue();
                    break;
            }

            return weekName;
        }
        else {
            throw new Exception("星期不能为空");
        }
    }
}